home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / SliderDualActing / SliderCellFine.m < prev    next >
Text File  |  1995-06-12  |  6KB  |  232 lines

  1.  
  2. /**************************************************************************
  3. *
  4. *        Object Name: SliderCellFine
  5. *
  6. *--------------------------------------------------------------------------
  7. *        Programmer:andrew stone
  8. *        Copyright (c) 1989,1990 Stone Design Corp.  All rights reserved. 
  9. ***************************************************************************/
  10.  
  11. #import "SliderCellFine.h"
  12. #import "SliderDualActing.h"
  13. #import <appkit/Application.h>
  14. #import <dpsclient/wraps.h>
  15. #import <math.h>
  16.  
  17.  
  18. /* Dragging 'resolution' of slider: how much the slider changes by */
  19.  
  20. #define FINE    .5                /* reduce altStep to 50% */
  21. #define SUPERFINE    .25            /* reduce altStep to 25% */
  22. #define DEFAULT_VAL    50.
  23. #define DEFAULT_MAX    100.
  24. #define DEFAULT_MIN    0.
  25. #define DEFAULT_ALT    1.
  26.  
  27. @implementation SliderCellFine
  28.  
  29. + new
  30. {
  31.     //sane defaults
  32.     self = [super new];
  33.     [self setAltStep:DEFAULT_ALT whole:YES default:DEFAULT_VAL];
  34.     [self setMax:DEFAULT_MAX allowHigher:YES min:DEFAULT_MIN allowLower:YES];
  35.     return self;
  36. }
  37.  
  38. - increment
  39. {
  40.     if (value+altStep <= maxValue) value += altStep;
  41.     else if (scfFlags.allowHigher)
  42.         { [self setMaxValue:value+altStep]; value += altStep; }
  43.     else return nil;    // failed to work
  44.     
  45.     [textPal setFloatValue:value];
  46.     return self;
  47. }
  48. - decrement
  49. {
  50.     if (value-altStep >= minValue) value -= altStep;
  51.     else if (scfFlags.allowLower)
  52.          { [self setMinValue:value+altStep]; value -= altStep; }
  53.     else return nil;    // failed to work
  54.  
  55.     [textPal setFloatValue:value];
  56.     return self;
  57. }
  58.  
  59.  
  60. - (double)checkValue:(double)val     // returns validated number
  61. {
  62.    if (val>= minValue && val<= maxValue) {
  63.       value = val;
  64.       return val;
  65.    } else if (val<minValue && scfFlags.allowLower) {
  66.       [self setMinValue:val];
  67.       value = val;
  68.       return val;
  69.    } else if (val>maxValue && scfFlags.allowHigher) {
  70.        [self setMaxValue:val];
  71.        value = val;
  72.        return val;
  73.     } else return value;      // no change allowed
  74. }
  75.  
  76. -(BOOL)isDecimal
  77.   return scfFlags.isDecimal;
  78. }
  79.  
  80. - (BOOL)continueTracking:(const NXPoint *)lastPoint
  81.               at:(const NXPoint *)currentPoint
  82.               inView:controlView
  83. {
  84.     NXEvent *e = [NXApp currentEvent];
  85.  
  86.     if  (e->flags & NX_ALTERNATEMASK) {
  87.         NXRect r;
  88.         double step = altStep;
  89.     
  90.         if (!lastPoint) lastPoint = currentPoint;
  91.     
  92.         if (e->flags & NX_SHIFTMASK) {
  93.               if (textPal) {
  94.                   [textPal setFloatingPointFormat:YES left:2 right:2];
  95.                 scfFlags.isDecimal =YES;
  96.             }
  97.             if (e->flags & NX_COMMANDMASK) step*=SUPERFINE; 
  98.             else step *= FINE;         
  99.         }
  100.         else if (scfFlags.isWhole) value = floor(value);
  101.  
  102.  
  103.         if (trackRect.size.width>trackRect.size.height) {
  104.             [self getKnobRect:&r flipped:NO];
  105.             if (r.origin.x+r.size.width<trackRect.size.width)
  106.                 r.size.width+=1.;
  107.                if (currentPoint->x >lastPoint->x) {
  108.                    value+=step;if (value>maxValue) value=maxValue;
  109.             } else if (currentPoint->x < lastPoint->x) {
  110.                     value -= step;if (value<minValue)value=minValue;
  111.             }
  112.         } else  {                 // is a vertical slider
  113.             [self getKnobRect:&r flipped:YES];
  114.             if (r.origin.y+r.size.height<trackRect.size.height)
  115.                 r.size.height+=1.;
  116.             if (currentPoint->y < lastPoint->y) {
  117.                 value+=step; if (value>maxValue) value=maxValue;
  118.             } else if (currentPoint->y > lastPoint->y) {
  119.                 value -= step; if (value<minValue)value=minValue;
  120.             }
  121.         }
  122.         PSsetgray(.5);        // Track gray 1.0
  123.         NXRectFill(&r);
  124.         [self drawKnob];
  125.         
  126.         [textPal setFloatValue:value];
  127.         if (scfFlags.sendContinuously) [controlView _sendIt];
  128.  
  129.         lastPoint = currentPoint;
  130.         return YES;
  131.     } 
  132.     else if  (e->flags & NX_COMMANDMASK) {
  133.         NXRect r;
  134.         if (trackRect.size.width>trackRect.size.height)
  135.             [self getKnobRect:&r flipped:NO];
  136.         else 
  137.             [self getKnobRect:&r flipped:YES];
  138.         value = defaultValue;
  139.         if (textPal) {
  140.             [textPal setFloatingPointFormat:NO left:4 right:0];
  141.             [textPal setFloatValue:value];
  142.             scfFlags.isDecimal = NO;
  143.         }
  144.         if (defaultMax) [self setMaxValue:defaultMax];
  145.         if (defaultMin) [self setMinValue:defaultMin];
  146.         PSsetgray(.5);
  147.         NXRectFill(&r);
  148.         [self drawKnob];
  149.         return YES;
  150.     } else {
  151.         BOOL retVal;
  152.           [textPal setFloatValue:value];
  153.          retVal =[super continueTracking:(const NXPoint *)lastPoint
  154.               at:(const NXPoint *)currentPoint
  155.               inView:controlView];
  156.           [textPal setFloatValue:value];  //YUP, two times is better than 1!
  157.         if (scfFlags.sendContinuously) [controlView _sendIt];
  158.         return retVal;
  159.      }
  160. }
  161.  
  162.  // Client Initialization Routines:
  163.  
  164.  // this method allows slider to setup what fine step will be
  165.  // and if we should keep it to a whole integer
  166.  
  167. - setAltStep:(double)step whole:(BOOL)flag default:(double)val
  168. {
  169.     scfFlags.isWhole = flag;
  170.     scfFlags.isDecimal = 1-flag;     // support for Clients rounding results
  171.     if (scfFlags.isWhole) [textPal setFloatingPointFormat:NO left:4 right:0]; 
  172.     altStep = step;
  173.     defaultValue = val;
  174.     value = val;
  175.     return self;
  176. }
  177.  
  178.  // set highest high and yes if you can surpass and lowest lows and surpass flag
  179.  
  180. - setMax:(double)max allowHigher:(BOOL)hi min:(double)min allowLower:(BOOL)lo
  181. {
  182.     defaultMax = max;
  183.     [self setMaxValue:max];
  184.     defaultMin = min;
  185.     [self setMinValue:min];
  186.     scfFlags.allowHigher = hi;
  187.     scfFlags.allowLower = lo;
  188.     return self;
  189. }
  190.  
  191.  // archive methods:   // not tested C.E.
  192. - read:(NXTypedStream *)stream
  193. {
  194.     [super read:stream];
  195.     NXReadTypes(stream,"sffff",&scfFlags,&altStep,
  196.                                     &defaultValue,&defaultMax,&defaultMin);
  197.     [self setMinValue:defaultMin];
  198.       [self setMaxValue:defaultMax];
  199.     return self;
  200. }
  201.  
  202. - write:(NXTypedStream *)stream
  203. {
  204.     [super write:stream];
  205.     NXWriteTypes(stream,"sffff",&scfFlags,&altStep,
  206.                                     &defaultValue,&defaultMax,&defaultMin);
  207.     return self;
  208. }
  209.  
  210.  // private and historical functions
  211.  
  212. - _setAlwaysSendUpAction:(BOOL)flag
  213. {
  214.      scfFlags.sendContinuously = flag;
  215.     return self;
  216. }
  217.  
  218. - setDefault:(double) def
  219. {
  220.    defaultValue = def;   // needed for GrayView
  221.    return self;
  222. }
  223.  
  224. - setTextPal:anObject
  225. {
  226.   textPal = anObject;
  227.   return self;
  228. }
  229.  
  230. @end
  231.